package src.application.Doppelkopf;

/**
 * Abstrakte Klasse zur Verwaltung der Spieler
 * 
 * Speichert Handkarten, Stichkarten des Spielers.
 * 
 * Grundlage für die KI
 * 
 * @author T. Schrödter
 */
public abstract class Spieler {
    private int punkte;
    protected Karte[] handkarten, stich;
    private String name;
    private boolean re;
    private int spielart=1;
    private int[] vorbehalte;
    public abstract String karteSpielen();
    public abstract int macheAnsage();
    
    /**
     * Erstellt einen neuen Spieler
     * Es wird ein Array für die Handkarten, sowie Stichkarten erzeugt. 
     * Es wird ein Array für die Vorbehalte erzeugt.
     */
    public Spieler()
    {
        handkarten = new Karte[10];
        stich = new Karte[4];
        vorbehalte= new int[]{0,0};
    }
    
    /**
     * Setzt die Werte auf die Anfangswerte zurück. Um ein neues Spiel zu starten
     */
    public void reset(){
        punkte = 0;
        stich = new Karte[4];
        handkarten = new Karte[10];
        spielart = 1;
        vorbehalte = new int[2];
    }
    
    /**
     * Setzt den Namen des Spielers
     * @param pName Name des Spielers
     */
    public void setName(String pName)
    {
        name = pName;
    }
    
    /**
     * Gibt die Partei des Spielers zurück
     * @return true wenn Re, sonst false
     */
    public boolean getRe()
    {
        bestimmePartei();
        return re;
    }
    
    /**
     * Setzt die Spielart, wichtig für KI
     * @param spiel Spielart
     */
    public void setSpielart(int spiel)
    {
        spielart = spiel;
    }
    
    /**
     * Wird aufgerufen, wenn ein Spieler ein Solo spielt, dann wird die Partei 
     * aller Spieler gesetzt
     * @param re Partei des Spielers
     */
    public void setRe(boolean re)
    {
        this.re = re;
    }
    
    /**
     * Bestimmt die Partei eines Spielers, wichtig für richtige Ansagemöglichkeiten
     * und für die KI
     */
    private void bestimmePartei()
    {
        if (spielart==1)
        {
            for (int i=0; i< handkarten.length; i++)
            {
                if (handkarten[i].getFarbe()=='k' && handkarten[i].getWert()==3)
                {
                    re = true;
                    break;
                }
            }
        }    
        // sonstige Fälle!
    }
 
    /**
     * Bestimmt, ob der Spieler eine Armut hat
     * Armut:
     *  - ohne Fuchs (Karo Ass : d 11) max 3 Trumpf
     *  - mit Fuchs max 4 Trumpf
     * 
     * @return true Spieler hat Armut, sonst false
     */
    public boolean getArmut()
    {
        boolean fuchs=false;
        int trumpf=0;
        
        for (int i=this.handkarten.length-1; i<=0; --i)
        {
            if (handkarten[i].getTrumpf())
                trumpf++;
            if ((handkarten[i].getFarbe()=='d')&&(handkarten[i].getWert()==11))
                fuchs=true;
        }
        
        // nicht mehr als 3 Trumpf oder höchstens vier Trumpf mit Fuchs
        return ((trumpf<=3)||((trumpf<=4)&&(fuchs)));
    }
    
    /**
     * Bestimmt ob der Spieler schmeißen kann
     * Regeln:
     *  - Spieler hat mehr als 80 Punkte auf der Hand
     *  - Spieler hat min 5 Könige
     *  - Spieler hat keine Karte höher als Fuchs (Karo Ass : d 11)
     * 
     * @return 
     */
    public boolean getSchmeissen()
    {
        int koenige=0, punkte=0;
        Karte high = handkarten[9];
        
        //gucken ob höchte Karte kleiner Fuchs
        if (high.getWert()>=4)
        {
            if (high.getFarbe()=='h')
                ;
            else
                return true;
        }
        
        //Punkte und Könige zählen
        for (int i=0; i<handkarten.length-1; ++i)
        {
            punkte += handkarten[i].getWert();
            
            if (handkarten[i].getWert()==4)
                koenige++;
        }
        
        return ((koenige>=5)||(punkte>=80));
    }
    
    
    /**
     * Gibt den Namen des Spielers zurück
     * @return Name des Spielers
     */
    public String getName()
    {
        return name;
    }
    
    /**
     * Setzt die Handkarten des Spielers. Am Anfang einer Spielrunde
     * @param pKarten Handkarten des Spielers
     */
    public void setKarten(Karte[] pKarten)
    {
        handkarten = pKarten;
    }
    
    /**
     * Setzt den aktuellen Stich
     * @param pStich aktueller Stich
     */
    public void setStich(Karte[] pStich)
    {
        stich = pStich;
    }
    
    /**
     * Bestimmt ob der Spieler Schweine hat (beide Karo Asse)
     * @return Spieler hat Schweine
     */
    public boolean getSchweine()
    {
        int anzFuchs=0;
        for (int i=0; i<handkarten.length-1; ++i)
        {
            if  ((handkarten[i].getFarbe()=='d') && (handkarten[i].getWert()==11))
            {
                anzFuchs++;
            }
        }
        
        return (anzFuchs==2);
    }
    
    /**
     * Bestimmt ob der Spieler Hochzeit hat (beide Re-Damen)
     * @return Spieler hat Hochzeit
     */
    public boolean getHochzeit()
    {
        int anzReD=0;
        for (int i=0; i<handkarten.length-1; ++i)
        {
            if  ((handkarten[i].getFarbe()=='k') && (handkarten[i].getWert()==3))
            {
                anzReD++;
            }
        }
        
        return (anzReD==2);
    }
  
    /**
     * Setzt die Vorbehalte des Spielers.
     * Wichtig für VorbehaltFrame und KI
     * @param i Spielart
     * @param j Schweine 1=ja 0=nein
     */
    public void setVorbehalte(int i, int j)
    {
        this.vorbehalte[0]=i;
        this.vorbehalte[1]=j;
    }
    
    /**
     * Gibt die Vorbehalte des Spielers zurück.
     * Wichtig für die KI
     * 
     * @return [0] Spielart, [1] Schweine 1=ja 0=nein
     */
    public int[] getVorbehalte() 
    {
        return vorbehalte;
    }
    
    /**
     * Bestimmt alle gültigen Karten des Spielers.
     * Hierbei werden die Regeln berücksichtigt.
     * Wichtig für Anzeige und KI
     * 
     * @return gültige Karten
     */
    public Karte[] spielbareKarten()
    {
       // System.out.println("spielbare Karten");
        Karte[] spielbar = new Karte[10];
        int aufspieler=0;
        //Karten am Anfang auf null setzen
        for (Karte k : spielbar)
        {
            k = null;
        }
        
        if ((stich[1]==null)&&(stich[2]==null)&&(stich[3]==null))
            aufspieler=0;
        if ((stich[1]!=null)&&(stich[2]!=null)&&(stich[3]!=null))
            aufspieler=1;
        if ((stich[1]==null)&&(stich[2]!=null)&&(stich[3]!=null))
            aufspieler=2;
        if ((stich[1]==null)&&(stich[2]==null)&&(stich[3]!=null))
            aufspieler=3;
        

        int i=0;
        
        if (aufspieler==0)
        {
            return handkarten;
        }
        else
        {
            // erste gespielt Karte Trumpf
            if (stich[aufspieler].getTrumpf())
            {
                for (int j=0; j<handkarten.length; ++j)
                {
                    if (handkarten[j]==null)
                    {
                        continue;
                    }
                    
                    if (handkarten[j].getTrumpf())
                    {
                        spielbar[i]=handkarten[j];
                        i++;
                    }
                }
                
                // Kein Trumpf mehr
                if (spielbar[0]==null)
                {
                    return handkarten;
                }
                else
                {
                    return spielbar;
                }
            }
            // Fehl aufgespielt
            else
            {
                char c = stich[aufspieler].getFarbe();
                for (int j=0; j<handkarten.length; ++j)
                {
                    if (handkarten[j]==null)
                    {
                        continue;
                    }
                    if ((handkarten[j].getTrumpf()==false) && (handkarten[j].getFarbe()==c))
                    {
                        spielbar[i]=handkarten[j];
                        i++;
                    }
                }
                
                // Kein Fehl der Farbe mehr
                if (spielbar[0]==null)
                {
                    return handkarten;
                }
                else
                {
                    return spielbar;
                }
               
            }
        }
    }
} // end of class

